package com.yuyou.fn.settlement.service.impl;

import com.github.wens.framework.service.impl.SuperServiceImpl;
import com.github.wens.mybatisplus.examples.Example;
import com.github.wens.mybatisplus.plugins.Page;
import com.yuyou.fn.common.exception.BusException;
import com.yuyou.fn.common.util.*;
import com.yuyou.fn.settlement.constant.FeeShareStatus;
import com.yuyou.fn.settlement.constant.FeeStatus;
import com.yuyou.fn.settlement.entity.Fee;
import com.yuyou.fn.settlement.entity.FeeCategory;
import com.yuyou.fn.settlement.mapper.FeeMapper;
import com.yuyou.fn.settlement.service.IFeeCategoryService;
import com.yuyou.fn.settlement.service.IFeeService;
import com.yuyou.fn.settlement.service.IMainAccountService;
import com.yuyou.fn.settlement.service.ISettlementService;
import com.yuyou.fn.settlement.vo.FeeDetailVo;
import com.yuyou.fn.settlement.vo.FeeQueryVo;
import com.yuyou.fn.settlement.vo.FeeSaveVo;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.List;

/**
 *
 * Fee 表数据服务层接口实现类
 *
 */
@Service
public class FeeServiceImpl extends SuperServiceImpl<FeeMapper, Fee,Long> implements IFeeService {

    @Resource
    private ISettlementService settlementService ;

    @Resource
    private IMainAccountService mainAccountService;

    @Resource
    private IFeeCategoryService feeCategoryService ;


    @Override
    public Page<Fee> findFeeByQuery(FeeQueryVo feeQueryVo, int pageNo, int pageSize) {
        Example<Fee> example = Fee.createExample();
        example.orderBy("createTime").desc();
        Example.Criteria criteria = example.createCriteria();
        CriteriaUtils.fillCondition(criteria,feeQueryVo);
        return findPageByExample(example,pageNo,pageSize );
    }

    @Override
    public void saveFee(FeeSaveVo feeSaveVo) {
        Fee fee = new Fee() ;
        BeanUtils.copyProperties(fee,feeSaveVo);
        if (fee.getShareStart()!=null && fee.getShareEnd()!=null && fee.getShareStart().getTime()>fee.getShareEnd().getTime()){
            throw new BusException("选择的时间开始日期小于结束日期");
        }


        fee.setReceiverMainAccountName(mainAccountService.findById(fee.getReceiverMainAccountId()).getName());

        if(fee.getFeeCategoryId() != null ){
            FeeCategory feeCategory = feeCategoryService.findById(fee.getFeeCategoryId());
            if( feeCategory.getNeedMultMainBody() == 1 && StringUtils.isEmpty( fee.getShareMainAccountIds() ) ){
                throw new BusException("请录入分摊主体");
            }

            if(feeCategory.getNeedShareTime() == 1 && ( fee.getShareStart() == null || fee.getShareEnd() == null  )){
                throw new BusException("请录入分摊时间");
            }

            fee.setFeeCategoryName(feeCategory.getName());
        }

        if(fee.getFeeId() == null ){
            fee.setShareStatus(FeeShareStatus.NOT_SHARE.ordinal());
            fee.setCreateTime(TimeUtils.now());
            fee.setUpdateTime(TimeUtils.now());
            insertSelective(fee);
        }else{
            fee.setUpdateTime(TimeUtils.now());
            updateSelectiveById(fee);
        }

    }

    @Transactional
    @Override
    public void auditingFee(Long feeId, Integer status) {

        Fee updateFee = new Fee();
        updateFee.setFeeId(feeId);
        updateFee.setStatus(status);
        updateSelectiveById(updateFee);

        if(status == FeeStatus.AUDITED.ordinal()  ){//审核通过
            afterAudited(feeId);
        }


    }

    private void afterAudited(Long feeId) {
        Fee fee = findById(feeId);

        if(fee.getBusId() != null ){//只能审核手工录入的成本
            throw new BusException("只能审核手工录入的成本") ;
        }


        FeeCategory feeCategory = feeCategoryService.findById(fee.getFeeCategoryId());
        if( feeCategory.getNeedMultMainBody() == 1 ){
            List<Long> accountIds =  Utils.toLongIds(fee.getShareMainAccountIds());
            BigDecimal eachAmount = BigDecimals.calProportion(fee.getAmount(), BigDecimal.ONE, BigDecimal.valueOf(accountIds.size()));
            for(Long accountId : accountIds ){
                settlementService.bookFeeIncome( accountId ,fee.getFeeCategoryId() ,fee.getReceiverMainAccountId(),eachAmount ,fee.getRemark() , fee.getFeeId(), fee.getCreateTime() );
                if(feeCategory.getNeedShareTime() != 1 ){
                    settlementService.shareFee(accountId ,fee.getFeeCategoryId(),fee.getReceiverMainAccountId(), eachAmount ,fee.getRemark() ,fee.getFeeId() ,fee.getCreateTime() );
                }
            }
        }else{
            settlementService.bookFeeIncome( fee.getMainAccountId(),fee.getFeeCategoryId() ,fee.getReceiverMainAccountId(),fee.getAmount() ,fee.getRemark() , fee.getFeeId(),fee.getCreateTime() );
            if(feeCategory.getNeedShareTime() != 1 ){
                settlementService.shareFee(fee.getMainAccountId(),fee.getFeeCategoryId(),fee.getReceiverMainAccountId(),fee.getAmount(),fee.getRemark() ,fee.getFeeId(),fee.getCreateTime() );
            }
        }

        if( feeCategory.getNeedShareTime() != 1 ){
            fee.setSharedAmount(fee.getAmount());
            fee.setShareStatus(FeeShareStatus.SHAREED.ordinal());
            updateSelectiveById(fee) ;
        }
    }

    @Override
    public void deleteFee(Long feeId) {
        Fee fee = findById(feeId);
        if(fee.getStatus() != 0 ){
            throw new BusException("已审核，不能删除");
        }
        deleteById(feeId);
    }

    @Override
    public Long countByFeeCategory(Long feeCategoryId) {
        Example<Fee> example = Fee.createExample();
        example.createCriteria().andEqualTo("feeCategoryId" ,feeCategoryId );
        return countByExample(example);
    }

    @Override
    public Fee findFeeByBudId(Long busId) {
        Example<Fee> example = Fee.createExample();
        example.createCriteria().andEqualTo("busId" ,busId );
        return findOneByExample(example);
    }


    @Override
    public FeeDetailVo findDetail(Long feeId) {
        FeeDetailVo feeDetailVo=new FeeDetailVo();
        Fee fee=this.findById(feeId);
        FeeCategory feeCategory=feeCategoryService.findById(fee.getFeeCategoryId());
        if (feeCategory!=null){
            BeanUtils.copyProperties(feeDetailVo,feeCategory);
        }
        BeanUtils.copyProperties(feeDetailVo,fee);
        return feeDetailVo;
    }
}